import math

from sklearn.model_selection import train_test_split
from sklearn.multioutput import MultiOutputRegressor
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error, make_scorer
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_absolute_percentage_error, adjusted_rand_score
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.ensemble import GradientBoostingRegressor
from src.python.util.getResoures import getData


def run():
    # 获取数据
    x_train, x_test, y_train, y_test = getData()
    # 定义梯度提升树回归预测模型
    gbdt = GradientBoostingRegressor(loss='ls'  # 均方差’ls’, 绝对损失’lad’, Huber损失’huber’和分位数损失’quantile’
                                     , learning_rate=0.1  # 学习率
                                     , n_estimators=100 # 弱学习器个数
                                     , subsample=1 # 采样比例 0~1
                                     , min_samples_split=2 # 内部节点再划分所需最小样本数
                                     , min_samples_leaf=1 # 叶子节点最少样本数
                                     , max_depth=40 # 决策树最大深度
                                     , random_state=6 # 随机数种子
                                     , verbose=0 # 不输出迭代过程
                                     , max_leaf_nodes=None # 最大叶子节点数，限制叶子节点可以缓解过拟合
                                     )
    # 转化为多标签回归模型
    model = MultiOutputRegressor(gbdt)
    # 训练
    print("------------------------------------------- 梯度提升树回归预测模型：-------------------------------------------")
    model.fit(x_train, y_train)
    y_pre = model.predict(x_test)
    # 评估分数
    mae = mean_absolute_error(y_pred=y_pre, y_true=y_test)
    print("平均绝对误差MAE:", mae)
    mse = mean_squared_error(y_pred=y_pre, y_true=y_test)
    print("均方根误差RMSE:", math.sqrt(mse))
    print("均方误差MSE:", mse)
    mape = mean_absolute_percentage_error(y_pred=y_pre, y_true=y_test)
    print("平均绝对百分比误差MAPE:", mape)


if __name__ == "__main__":
    run()
